package MAgentAssignment.gui;


import MAgentAssignment.ontology.FlightOntology;
import MAgentAssignment.ontology.FlightVocabulary;
import MAgentAssignment.ontology.actions.CloseAirport;
import MAgentAssignment.ontology.actions.CreateAirpot;
import MAgentAssignment.ontology.actions.CreateNewFlight;
import MAgentAssignment.ontology.actions.Land;
import MAgentAssignment.ontology.concepts.Airport;
import MAgentAssignment.ontology.concepts.Flight;
import jade.content.lang.Codec;
import jade.content.lang.sl.SLCodec;
import jade.content.onto.Ontology;
import jade.core.AID;
import jade.core.Agent;
import jade.core.behaviours.CyclicBehaviour;
import jade.core.behaviours.OneShotBehaviour;
import jade.core.behaviours.TickerBehaviour;
import jade.domain.DFService;
import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.FIPAAgentManagement.ServiceDescription;
import jade.domain.FIPAException;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;
import jade.lang.acl.UnreadableException;

import java.io.IOException;

/**
 * Created by IntelliJ IDEA.
 * User: prageeth
 * Date: 2/14/12
 * Time: 6:52 PM
 * To change this template use File | Settings | File Templates.
 */
public class InterfaceAgent extends Agent
{
    public static String agentName = "GUI";
    private MonitorGUI monitorGUI;
    private Codec codec = new SLCodec();
    private Ontology ontology = FlightOntology.getInstance();

    @Override protected void setup()
    {

        getContentManager().registerLanguage( codec );
        getContentManager().registerOntology( ontology );
        monitorGUI = new MonitorGUI( this );
        monitorGUI.showGui();
        agentName = getAID().getLocalName();
        ServiceDescription sd = new ServiceDescription();
        sd.setType( "GUI" );
        sd.setName( getLocalName() );
        DFAgentDescription dfd = new DFAgentDescription();
        dfd.setName( getAID() );
        dfd.addServices( sd );
        try
        {
            DFService.register( this, dfd );
        }
        catch( FIPAException fe )
        {
            fe.printStackTrace();
        }

        addBehaviour( new TickerBehaviour( this, 100 )
        {
            @Override protected void onTick()
            {
                monitorGUI.tickStep();
            }
        } );

        addBehaviour( new CyclicBehaviour()
        {
            @Override public void action()
            {
                ACLMessage msg = receive( MessageTemplate.MatchPerformative( ACLMessage.INFORM ) );
                if( msg != null )
                {
                    Object contentObject = null;
                    try
                    {
                        contentObject = msg.getContentObject();
                    }
                    catch( UnreadableException e )
                    {
                        e.printStackTrace();
                    }
                    if( contentObject != null && contentObject instanceof CloseAirport )
                    {
                        CloseAirport closeAirport = (CloseAirport) contentObject;
                        monitorGUI.airpotClosed( closeAirport.getAirport() );
                    }
                    if( contentObject != null && contentObject instanceof CreateAirpot )
                    {
                        CreateAirpot createAirpot = (CreateAirpot) contentObject;
                        monitorGUI.airpotStarted( createAirpot.getAirport() );
                    }
                    else if( contentObject != null && contentObject instanceof CreateNewFlight )
                    {
                        final CreateNewFlight createNewFlight = (CreateNewFlight) contentObject;
                        monitorGUI.flightStarted( createNewFlight.getFlight(), new FlightTravelListener()
                        {
                            public void arrived( final FlightIcon flightIcon )
                            {
                                System.out.println( "Flight Arrived " );
                                addBehaviour( new OneShotBehaviour()
                                {
                                    @Override public void action()
                                    {
                                        informFlightArrival( flightIcon.getFlight() );
                                    }
                                } );
                            }
                        } );
                    }
                }
                //                else
                //                {
                //                    block();
                //                }
            }
        } );
    }

    protected void informGUIOperation( Object obj )
    {
        System.out.println( "Handling GUI Operation" );
    }


    public void informFlightArrival( Flight flight )
    {
        //        DFAgentDescription template = new DFAgentDescription();
        //        ServiceDescription sd = new ServiceDescription();
        //        sd.setType( "AIRLINE" );
        //        template.addServices( sd );
        try
        {
            //            DFAgentDescription[] result = DFService.search( this, template );
            //            for( DFAgentDescription dfAgentDescription : result )
            //            {
            ACLMessage msg = new ACLMessage( ACLMessage.INFORM );
            Land land = new Land();
            land.setFlight( flight );
            land.setArrivalTimeInMillis( System.currentTimeMillis() );
            msg.setContentObject( land );
            //                msg.addReceiver( new AID( dfAgentDescription.getName().getLocalName(), AID.ISLOCALNAME ) );
            msg.addReceiver( new AID( flight.getAgentName(), AID.ISLOCALNAME ) );
            send( msg );
            //            }
        }
        catch( IOException e )
        {
            e.printStackTrace();
        }
        //        catch( FIPAException fe )
        //        {
        //            fe.printStackTrace();
        //        }
    }

}
